/**
 * 
 */
package com.imooc.security.core.social.qq.connet;

import java.nio.charset.Charset;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.social.oauth2.AccessGrant;
import org.springframework.social.oauth2.OAuth2Template;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

/**
 * 因为原生的OAuth2Template不支持将text/html转成Map,所以需要自己重写
 */
public class QQOAuth2Template extends OAuth2Template {
	
	private Logger logger = LoggerFactory.getLogger(getClass());

	public QQOAuth2Template(String clientId, String clientSecret, String authorizeUrl, String accessTokenUrl) {
		super(clientId, clientSecret, authorizeUrl, accessTokenUrl);
		//设为true 父类OAuth2Template中exchangeForAccess方法中的params.set("client_id", clientId);params.set("client_secret", clientSecret);才会执行
		setUseParametersForClientAuthentication(true);
	}


	/**
	 * 原生的OAuth2Template的postForAccessGrant方法发送请求后将响应中的Json封装成Map,然后用Map生成一个AccessGrant的实例，但是QQ返回来的不是json数据
	 * 所以需要自己重写处理
	 * @param accessTokenUrl
	 * @param parameters
	 * @return
	 */
	@Override
	protected AccessGrant postForAccessGrant(String accessTokenUrl, MultiValueMap<String, String> parameters) {
		String responseStr = getRestTemplate().postForObject(accessTokenUrl, parameters, String.class);
		
		logger.info("获取accessToke的响应："+responseStr);
		
		String[] items = StringUtils.splitByWholeSeparatorPreserveAllTokens(responseStr, "&");

		//将QQ响应的字符串解析
		String accessToken = StringUtils.substringAfterLast(items[0], "=");
		Long expiresIn = new Long(StringUtils.substringAfterLast(items[1], "="));
		String refreshToken = StringUtils.substringAfterLast(items[2], "=");

		//封装
		return new AccessGrant(accessToken, null, refreshToken, expiresIn);
	}


	/**
	 * 覆盖父类的RestTemplate，添加支持text/html的转换器
	 * @return
	 */
	@Override
	protected RestTemplate createRestTemplate() {
		RestTemplate restTemplate = super.createRestTemplate();
		//添加可以处理text/html的响应的转换器
		restTemplate.getMessageConverters().add(new StringHttpMessageConverter(Charset.forName("UTF-8")));
		return restTemplate;
	}

}
